using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Windows;

namespace ReactiveCode
{
    using Statements;
    using Util;

    public class ReactiveHost: IDisposable
    {
        #region Scheduler

        StateChangeScheduler _scheduler = StateChangeScheduler.Current;
        internal StateChangeScheduler Scheduler
        {
            get { return _scheduler; }
        }
        
        #endregion

        Time _creationTime = Time.Current;
        internal Time CreationTime
        {
            get { return _creationTime; }
        }

        ~ReactiveHost()
        {
            Dispose(false);
        }
        public void Dispose()
        {
            Dispose(true);
        }
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
                GC.SuppressFinalize(this);
            foreach(var call in _calls.ToList())
                call.Dispose();
        }


        internal LinkedList<RootStatement> _calls = new LinkedList<RootStatement>();
        public IReactive Call(ReactiveMethod method, bool enable = true)
        {
            Contract.Requires(method != null);
            var root = new RootStatement(this, method);
            if (enable)
                root.Enabled = true;
            return root;
        }
        public IReactive<T> Call<T>(ReactiveMethod<T> method, bool enable = true)
        {
            Contract.Requires(method != null);
            var root = new RootStatement<T>(this, method);
            if (enable)
                root.Enabled = true;
            return root;
        }
        public IReactive Call(ReactiveStatement statement, bool enable = true)
        {
            Contract.Requires(statement != null);
            return Call(new ReactiveMethod(statement), enable);
        }
    }
}